/**
@author		Jong Min, Lee
@date		  02/07/2014
@breif		monitor group property

copyright(c) Tae Young Soft. All right reserved. 2014
*/
#pragma once

#include <vector>
#include "Taurus_Util/Macros.h"

//forward declarations
class CMonitorWnd;
class CStudyWorkSpace;

/**
@brief  monitor group
*/
class CMonitorGroup
{
public:
  friend class CMonitorGroupProperty;
  /**
  @brief		default constructor
  */
  CMonitorGroup(){}

  /**
  @brief		destructor
  */
  ~CMonitorGroup();

  /**
  @brief		get number of monitor g
  @return		the number of monitors
  */
  inline unsigned getNumItems() const
  {
    return m_theItems.size();
  }

  /**
  @brief		access a monitor window item
  @param		index the index number of monitor window item to be accessed
  @return		pointer to monitor window if found, nullptr if not
  */
  const CMonitorWnd* getItem(unsigned index) const
  {
    if(index >= m_theItems.size()) return nullptr;

    return m_theItems[index];
  }

  /**
  @brief		the index number of monitor window
  @param		monitorWnd pointer to monitor window
  @param    index variable in which the index number of monitor window is stored
  @return		TRUE if found, FALSE if not
  */
  BOOL getIndex(const CMonitorWnd* monitorWnd,
                unsigned int& index) const;
  /**
  @brief		check whether monitor window is exist in monitor group
  @param		monitorWnd pointer to monitor window
  @return		TRUE if exist, FALSE if not
  */
  BOOL isExist(const CMonitorWnd* monitorWnd) const;

  /**
  @brief		get number of study workspace in a monitor
  @param		index the index number of monitor window item
  @return		the number of study workspace
  */
  unsigned int getNumSWSs(const unsigned int index) const;

  /**
  @brief		add study workspace to monitor window
  @param		index the index number of monitor window item
  @param    sws study work space
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD addSWS(const unsigned int index, const CStudyWorkSpace& sws);

  /**
  @brief		access study work space
  @param		monitorIndex the index number of monitor window item
  @param    swsIndex the index number of study work space item
  @return		pointer to study work space if found, NULL if not
  */
  const CStudyWorkSpace* getSWS(const unsigned int monitorIndex,
                                const unsigned int swsIndex) const;

  /**
  @brief		clear study work space group
  */
  void clearSWSGroup();

private:
  DISALLOW_COPY_AND_ASSIGN(CMonitorGroup);

private:
  //monitor items
  std::vector<CMonitorWnd*> m_theItems;

  //study view workspace group
  std::vector<std::vector<const CStudyWorkSpace*>*> m_theSWSGroup;
};

/**
@brief		monitor group property
*/
class CMonitorGroupProperty
{
public:
  /**
  @brief		default constructor
  */
  CMonitorGroupProperty();

  /**
  @brief		destructor
  */
  ~CMonitorGroupProperty();

  /**
  @brief		group monitors by using monitor layout string
  @param		pszLayout pointer to monitor layout string
  @param    arrMonitorWnds array of monitor windows to be grouped
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD groupMonitors(const TCHAR* pszLayout, std::vector<CMonitorWnd*>& arrMonitrWnds);

  /**
  @brief		get the number of monitor groups
  @return		the number of monitor groups
  */
  inline unsigned getNumItems() const
  {
    return m_nNumItems;
  }

  /**
  @brief		access a monitor group
  @param		index the index number of monitor group to be accessed
  @return		pointer to monitor group if found, nullptr if not
  */
  const CMonitorGroup* getItem(unsigned index) const;

  /**
  @brief		find a monitor group by using pointer to monitor window
  @param		monitorWnd pointer to monitor window
  @param    index variable the index number of monitor group
  @return	  pointer to monitor group if found, NULL if not
  */
  const CMonitorGroup* findItem(const CMonitorWnd* monitorWnd,
                                unsigned int* index) const;

  /**
  @brief		add study work space to a monitor of monitor group
  @param		groupIndex the index number of group
  @param    monitorIndex the index number of monitor
  @param    sws study work space
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD addSWS(const unsigned int groupIndex,
               const unsigned int monitorIndex,
               const CStudyWorkSpace& sws);

  /**
  @brief		clear all study work space groups
  */
  void clearSWSGroups();

  /**
  @brief		convert current grouping to string
  @return		monitor group string
  */
  CString convertToStr() const;

  /**
  @brief		remove all monitor groups
  */
  void removeAllGroups();

private:
  DISALLOW_COPY_AND_ASSIGN(CMonitorGroupProperty);

  /**
  @brief		parse monitor layout string
  @param		pszLayout monitor layout string
  @param    arrMonitorCount array which monitor counts are stored
  @param    nTotalCount variable in which total monitor count
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD parseLayoutStr(const TCHAR* pszLayout,
                       std::vector<unsigned>& arrMonitorCount,
                       unsigned int& nTotalCount);
private:
  //monitor groups
  CMonitorGroup** m_arrItems;
  
  //the number of monitor groups
  unsigned m_nNumItems;
};

